using Infrastructure.Attribute;
using Infrastructure.Extensions;
using ZR.Model.ProdManage.Dto;
using ZR.Model.ProdManage;
using ZR.Repository;
using ZR.Service.ProdManage.IProdManageService;
using Infrastructure;
using Microsoft.AspNetCore.Http.HttpResults;
using Org.BouncyCastle.Bcpg;
using System.Numerics;
using System.Threading.Tasks;

namespace ZR.Service.ProdManage
{
    /// <summary>
    /// 二级包装Service业务层处理
    /// </summary>
    [AppService(ServiceType = typeof(IProdTwoPackService), ServiceLifetime = LifeTime.Transient)]
    public class ProdTwoPackService : BaseService<ProdTwoPack>, IProdTwoPackService
    {
        /// <summary>
        /// 查询二级包装列表
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public PagedInfo<ProdTwoPackDto> GetPageList(ProdTwoPackQueryDto parm)
        {
            var predicate = QueryExp(parm);

            var response = Queryable()
                .Where(predicate.ToExpression())
                .ToPage<ProdTwoPack, ProdTwoPackDto>(parm);

            return response;
        }


        /// <summary>
        /// 获取详情
        /// </summary>
        /// <param name="PackId"></param>
        /// <returns></returns>
        public ProdTwoPack GetInfo(string PackId)
        {
            var response = Queryable()
                .Where(x => x.PackId == PackId)
                .First();

            return response;
        }

        /// <summary>
        /// 添加二级包装
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public ProdTwoPack AddProdTwoPack(ProdTwoPack model)
        {
            return Insertable(model).ExecuteReturnEntity();
        }

        /// <summary>
        /// 修改二级包装
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int UpdateProdTwoPack(ProdTwoPack model)
        {
            return Update(model, true);
        }

        /// <summary>
        /// 导入二级包装
        /// </summary>
        /// <returns></returns>
        public (string, object, object) ImportProdTwoPack(List<ProdTwoPack> list)
        {
            var x = Context.Storageable(list)
                .SplitInsert(it => !it.Any())
                .SplitError(x => x.Item.PackId.IsEmpty(), "包装id不能为空")
                .SplitError(x => x.Item.DmsOrderNo.IsEmpty(), "DMS订单不能为空")
                .SplitError(x => x.Item.PlanNo.IsEmpty(), "计划号不能为空")
                .SplitError(x => x.Item.PackBatchNo.IsEmpty(), "装箱批次不能为空")
                .SplitError(x => x.Item.PackNo.IsEmpty(), "箱号不能为空")
                .SplitError(x => x.Item.PackStatus.IsEmpty(), "装箱状态（1进行2完成3已装箱4已装柜9取消）不能为空")
                .SplitError(x => x.Item.PackingType.IsEmpty(), "包装类型不能为空")
                .SplitError(x => x.Item.PrintState.IsEmpty(), "打印状态(已打印、未打印)不能为空")
                .SplitError(x => x.Item.PostbackState.IsEmpty(), "上传状态(Y成功N失败W等待)不能为空")
                //.WhereColumns(it => it.UserName)//如果不是主键可以这样实现（多字段it=>new{it.x1,it.x2}）
                .ToStorage();
            var result = x.AsInsertable.ExecuteCommand();//插入可插入部分;

            string msg = $"插入{x.InsertList.Count} 更新{x.UpdateList.Count} 错误数据{x.ErrorList.Count} 不计算数据{x.IgnoreList.Count} 删除数据{x.DeleteList.Count} 总共{x.TotalList.Count}";
            Console.WriteLine(msg);

            //输出错误信息               
            foreach (var item in x.ErrorList)
            {
                Console.WriteLine("错误" + item.StorageMessage);
            }
            foreach (var item in x.IgnoreList)
            {
                Console.WriteLine("忽略" + item.StorageMessage);
            }

            return (msg, x.ErrorList, x.IgnoreList);
        }

        /// <summary>
        /// 导出二级包装
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public PagedInfo<ProdTwoPackDto> ExportList(ProdTwoPackQueryDto parm)
        {
            var predicate = QueryExp(parm);

            var response = Queryable()
                .Where(predicate.ToExpression())
                .Select((it) => new ProdTwoPackDto()
                {
                }, true)
                .ToPage(parm);

            return response;
        }

        /// <summary>
        /// 查询导出表达式
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        private static Expressionable<ProdTwoPack> QueryExp(ProdTwoPackQueryDto parm)
        {
            var predicate = Expressionable.Create<ProdTwoPack>();

            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.DmsOrderNo), it => it.DmsOrderNo == parm.DmsOrderNo);
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.PlanNo), it => it.PlanNo == parm.PlanNo);
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.PackBatchNo), it => it.PackBatchNo == parm.PackBatchNo);
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.PackNo), it => it.PackNo == parm.PackNo);
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.PackStatus), it => it.PackStatus == parm.PackStatus);
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.PackingType), it => it.PackingType == parm.PackingType);
            return predicate;
        }

        /// <summary>
        /// 推送二级包装
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public async Task<bool> CogradientProdTwoPack(List<WmsTwoPackDto> list)
        {
            if (list == null || list.Count == 0) throw new CustomException("推送的二级包装信息为空");
            //判断是否已经推送计划
            List<string> codes = list.Select(x => x.planNo).Distinct().ToList();
            List<ProdTwoPack> oldList = Queryable().Where(it => codes.Contains(it.PlanNo)).ToList();
            List<string> packIds = oldList.Select(x => x.PackId).Distinct().ToList();
            List<ProdTwoPackDetail> oldDetailList = this.Context.Queryable<ProdTwoPackDetail>().Where(it => packIds.Contains(it.TwoPackId)).ToList();

            //新增修改实体
            List<ProdTwoPack> addList = new List<ProdTwoPack>();
            List<ProdTwoPack> updateList = new List<ProdTwoPack>();
            List<ProdTwoPackDetail> addDetailList = new List<ProdTwoPackDetail>();
            List<ProdTwoPackDetail> updateDetailList = new List<ProdTwoPackDetail>();
            foreach (var item in list)
            {
                ProdTwoPack oldPack = oldList.FirstOrDefault(it => it.PlanNo == item.planNo && it.PackNo == item.packNo);
                //已经昨晚且执行上传至wms
                if (oldPack.PostbackState == "Y") continue;
                else if (oldPack.PostbackState == "N") continue;
                //已经开始装箱
                if (oldPack.PackStatus != "0") continue;

                if (oldPack == null)
                {
                    //执行新增
                    ProdTwoPack pack = new ProdTwoPack()
                    {
                        PackId = Guid.NewGuid().ToString().ToUpper(),
                        DmsOrderNo = item.dmsOrderNo,
                        PlanNo = item.planNo,
                        WareCode = item.wareCode,
                        PackBatchNo = item.packBatchNo,
                        PackNo = item.packNo,
                        PackStartTime = item.packStartTime,
                        PackEndTime = item.packEndTime,
                        PackStatus = item.packStatus,
                        PackingType = item.packingType,
                        PackLength = item.packLength,
                        PackWidth = item.packWidth,
                        PackHeight = item.packHeight,
                        PackWeight = item.packWeight,
                        NetWeight = item.netWeight,
                        GrossWeight = item.grossWeight,
                        Version = item.version,
                        CarType = item.carType,
                        TechnologyNo = item.technologyNo,
                        ReferencePack = item.referencePack,
                        PrintState = "未打印",
                        PostbackState = "W",
                        CreateBy = "wms",
                        CreateTime = DateTime.Now,
                        Remark = item.remark,
                    };
                    addList.Add(pack);

                    foreach (var deitem in item.detail)
                    {
                        //新增明细
                        ProdTwoPackDetail detail = new ProdTwoPackDetail()
                        {
                            DetailId = Guid.NewGuid().ToString().ToUpper(),
                            TwoPackId = pack.PackId,
                            ItemStatus = deitem.itemStatus,
                            OnePackNo = deitem.onePackNo,
                            PackType = deitem.packType,
                            PartDesc = deitem.partDesc,
                            RelaGroupId = deitem.relaGroupId,
                            Vin = deitem.vin,
                            PackNum = deitem.packNum,
                            PackUserId = deitem.packUserId,
                            PackTime = deitem.packTime,
                            PartCode = deitem.partCode,
                            SupplierCode = deitem.supplierCode,
                        };
                        addDetailList.Add(detail);
                    }
                }
                else
                {
                    //执行修改 
                    oldPack.DmsOrderNo = item.dmsOrderNo;
                    oldPack.PlanNo = item.planNo;
                    oldPack.WareCode = item.wareCode;
                    oldPack.PackBatchNo = item.packBatchNo;
                    oldPack.PackNo = item.packNo;
                    oldPack.PackStartTime = item.packStartTime;
                    oldPack.PackEndTime = item.packEndTime;
                    oldPack.PackStatus = item.packStatus;
                    oldPack.PackingType = item.packingType;
                    oldPack.PackLength = item.packLength;
                    oldPack.PackWidth = item.packWidth;
                    oldPack.PackHeight = item.packHeight;
                    oldPack.PackWeight = item.packWeight;
                    oldPack.NetWeight = item.netWeight;
                    oldPack.GrossWeight = item.grossWeight;
                    oldPack.Version = item.version;
                    oldPack.CarType = item.carType;
                    oldPack.TechnologyNo = item.technologyNo;
                    oldPack.ReferencePack = item.referencePack;
                    oldPack.UpdateBy = "wms";
                    oldPack.UpdateTime = DateTime.Now;
                    oldPack.Remark = item.remark;
                    updateList.Add(oldPack);

                    //查询明细信息
                    foreach (var deitem in item.detail)
                    {
                        ProdTwoPackDetail oldDetail = oldDetailList.FirstOrDefault(it => it.TwoPackId == oldPack.PackId && it.PartCode == deitem.partCode);
                        if (oldDetail == null)
                        {
                            //新增明细
                            ProdTwoPackDetail detail = new ProdTwoPackDetail()
                            {
                                DetailId = Guid.NewGuid().ToString().ToUpper(),
                                TwoPackId = oldPack.PackId,
                                ItemStatus = deitem.itemStatus,
                                OnePackNo = deitem.onePackNo,
                                PackType = deitem.packType,
                                PartDesc = deitem.partDesc,
                                RelaGroupId = deitem.relaGroupId,
                                Vin = deitem.vin,
                                PackNum = deitem.packNum,
                                PackUserId = deitem.packUserId,
                                PackTime = deitem.packTime,
                                PartCode = deitem.partCode,
                                SupplierCode = deitem.supplierCode,
                            };
                            addDetailList.Add(detail);
                        }
                        else
                        {
                            //修改明细
                            if (oldDetail.PartCode != deitem.partCode || oldDetail.SupplierCode != deitem.supplierCode || oldDetail.PackNum != deitem.packNum)
                            {
                                oldDetail.ItemStatus = deitem.itemStatus;
                                oldDetail.OnePackNo = deitem.onePackNo;
                                oldDetail.PackType = deitem.packType;
                                oldDetail.PartDesc = deitem.partDesc;
                                oldDetail.RelaGroupId = deitem.relaGroupId;
                                oldDetail.Vin = deitem.vin;
                                oldDetail.PackNum = deitem.packNum;
                                oldDetail.PackUserId = deitem.packUserId;
                                oldDetail.PackTime = deitem.packTime;
                                oldDetail.PartCode = deitem.partCode;
                                oldDetail.SupplierCode = deitem.supplierCode;
                                updateDetailList.Add(oldDetail);
                            }
                        }

                    }
                }
            }


            //执行事务
            var db = this.Context.Ado;
            var res = await db.UseTranAsync(async () =>
            {
                //新增-修改包装
                if (addList.Count > 0) await db.Context.Insertable(addList).ExecuteCommandAsync();
                if (updateList.Count > 0) await db.Context.Updateable(updateList).ExecuteCommandAsync();

                //新增-修改包装明细
                if (addDetailList.Count > 0) await db.Context.Updateable(addDetailList).ExecuteCommandAsync();
                if (updateDetailList.Count > 0) await db.Context.Updateable(updateDetailList).ExecuteCommandAsync();

                return true;
            });
            if (res.Data == false)
            {
                throw new CustomException(res.ErrorMessage);
            }

            return true;
        }
    }
}